package com.shuke.medical.insure.utils;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.shuke.medical.insure.eums.IResultCode;
import com.shuke.medical.insure.eums.RetEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.Serializable;

/***
 * @title R
 * @description
 * @author baiji
 * @version 1.0.0
 * @create 2023/9/1 14:40
 **/
public class R<T> implements Serializable {
    private static final Logger log = LoggerFactory.getLogger(R.class);
    private static final long serialVersionUID = 1L;
    private Integer ret;
    private T data;
    private String msg;
    private boolean success;

    public boolean isSuccess() {
        return this.success;
    }

    private void setSuccess(boolean bl) {
        this.success = bl;
    }

    public int getRet() {
        return this.ret;
    }

    private void setRet(Integer ret) {
        this.ret = ret;
    }

    public String getMsg() {
        return this.msg;
    }

    private void setMsg(String msg) {
        this.msg = msg;
    }

    private void setData(T data) {
        this.data = data;
    }

    private R(Integer ret, T data, String msg) {
        this.ret = ret;
        this.data = data;
        this.msg = msg;
        this.success = RetEnum.SUCCESS.getCode() == ret;
    }

    private R(String msg, Boolean rollbackDb) {
        this.ret = RetEnum.ROLLBACK_DB.getCode();
        this.data = null;
        this.msg = msg;
        this.success = false;
    }

    public boolean success() {
        return this.success;
    }

    public static <T> R<T> ok() {
        return restResult(null, RetEnum.SUCCESS.getCode(), null);
    }

    public static <T> R<T> ok(T data) {
        return restResult(data, RetEnum.SUCCESS.getCode(), null);
    }

    public static <T> R<T> ok(T data, String msg) {
        return restResult(data, RetEnum.SUCCESS.getCode(), msg);
    }

    public static <T> R<T> ok(R<T> r, String msg) {
        return restResult(r, msg, RetEnum.SUCCESS.getCode());
    }

    public static <T> R<T> ok(R<T> r) {
        return restResult(r, null, RetEnum.SUCCESS.getCode(), (String) null);
    }

    public static <T> R<T> ok(R<T> r, T data) {
        return restResult(r, data, RetEnum.SUCCESS.getCode(), (String) null);
    }

    public static <T> R<T> ok(R<T> r, T data, String msg) {
        return restResult(r, data, RetEnum.SUCCESS.getCode(), msg);
    }

    public static <T> R<T> failed(RetEnum retEnum) {
        T data = null;
        if (RetEnum.NO_DATA.equals(retEnum)) {
            data = (T) new JSONObject();
        } else if (RetEnum.NO_LIST_DATA.equals(retEnum)) {
            data = (T) new JSONArray();
        }

        return restResult(data, retEnum.getCode(), retEnum.getMsg());
    }

    public static <T extends IResultCode> R<T> failed(IResultCode resultCode) {
        return restResult(null, (Integer) resultCode.getCode(), (String) resultCode.getMsg());
    }

    public static <T> R<T> failed() {
        return restResult(null, (Integer) RetEnum.FAIL.getCode(), (String) RetEnum.FAIL.getMsg());
    }

    public static <T> R<T> failed(Integer ret, String msg) {
        return restResult(null, (Integer) ret, (String) msg);
    }

    public static <T> R<T> failed(String msg) {
        return restResult(null, (Integer) RetEnum.FAIL.getCode(), (String) msg);
    }

    public static <T> R<T> failed(T data) {
        return restResult(data, (Integer) RetEnum.FAIL.getCode(), (String) null);
    }

    public static <T> R<T> failed(T data, String msg) {
        return restResult(data, RetEnum.FAIL.getCode(), msg);
    }

    public static <T> R<T> failed(R<T> r) {
        return restResult(r, null, RetEnum.FAIL.getCode(), (String) null);
    }

    public static <T> R<T> failed(R<T> r, Integer ret, String msg) {
        return restResult(r, null, ret, msg);
    }

    public static <T> R<T> failed(R<T> r, String msg) {
        return restResult(r, null, RetEnum.FAIL.getCode(), msg);
    }

    public static <T> R<T> failed(R<T> r, T data) {
        return restResult(r, data, RetEnum.FAIL.getCode(), (String) null);
    }

    public static <T> R<T> failed(R<T> r, T data, String msg) {
        return restResult(r, data, RetEnum.FAIL.getCode(), msg);
    }

    public static <T> R<T> rollbackDbResult(String msg) {
        R<T> apiResult = new R(msg, Boolean.TRUE);
        return apiResult;
    }

    private static <T> R<T> restResult(T data, Integer ret, String msg) {
        R<T> apiResult = new R(ret, data, msg);
        return apiResult;
    }

    private static <T> R<T> restResult(R<T> apiResult, String msg, Integer ret) {
        apiResult.setMsg(msg);
        apiResult.setSuccess(RetEnum.SUCCESS.getCode().equals(ret));
        apiResult.setRet(ret);
        return apiResult;
    }

    private static <T> R<T> restResult(R<T> apiResult, T data, Integer ret, String msg) {
        apiResult.setRet(ret);
        apiResult.setSuccess(RetEnum.SUCCESS.getCode().equals(ret));
        apiResult.setData(data);
        apiResult.setMsg(msg);
        return apiResult;
    }

    public static <T> R<T> status(boolean flag) {
        return flag ? ok() : failed("操作失败");
    }

    public <T> T getData() {
        return this.data != null ? (T) this.data : null;
    }

    public String toJsonString() {
        return JSONObject.toJSONString(this);
    }

    @Override
    public String toString() {
        return "R(ret=" + this.getRet() + ", data=" + this.getData() + ", msg=" + this.getMsg() + ", success=" + this.isSuccess() + ")";
    }

    public R() {
    }

    public R(Integer ret, T data, String msg, boolean success) {
        this.ret = ret;
        this.data = data;
        this.msg = msg;
        this.success = success;
    }
}
